/*************************************************************************
> File Name: MyVector.hpp
> Author: hzy
> Created Time: 2023-08-17 09:58:52
> Description:我自己写的类似Vector容器
************************************************************************/
#include "MyVector.h"

template <class T>
MyVector<T>::MyVector()
{
    Size = 0;
    Capacity = 1;
    this->Data = new T[Capacity];
}

template <class T>
MyVector<T>::~MyVector()
{
    if (Data != NULL)
    {
        delete[] Data;
    }
}

// 获取动态数组的容量
template <class T>
int MyVector<T>::getCapacity()
{
    return this->Capacity;
}

// 获取动态数组的大小
template <class T>
int MyVector<T>::getSize()
{
    return this->Size;
}

// 判断动态数组是否为空
template <class T>
bool MyVector<T>::isEmpty()
{
    return Size == 0;
}

// 尾插法插入
template <class T>
void MyVector<T>::pushBack(T value)
{
    // 动态数组已经满了
    if (Size == Capacity)
    {
        // 将动态数组容量扩大两倍
        reSize(Capacity * 2);
    }
    Data[Size++] = value;
}

// 删除末尾的数据元素
template <class T>
void MyVector<T>::popBack()
{
    if (Size > 0)
    {
        Size--;
        if (Size <= Capacity / 2)
        {
            reSize(Capacity / 2);
        }
    }
}

// 清空数组元素
template <class T>
void MyVector<T>::Clear()
{
    delete Data;
    Data = NULL;
    Capacity = 0;
    Size = 0;
}

// 重载[]操作符(访问指定位置的元素)
template <class T>
T &MyVector<T>::operator[](int location) const
{
    if (location >= 0 && location < this->Size)
    {
        return Data[location];
    }
    else
    {
        throw out_of_range("访问位置异常(0 < location < size)");
    }
}

// 按位置location查找数组元素
template <class T>
T &MyVector<T>::at(int location) const
{
    int *temp = Data;
    if (location >= 0 && location < this->Size)
    {
        for (int i = 0; i < location; i++)
        {
            temp++;
        }
    }
    else
    {
        throw out_of_range("访问位置异常(0 < location < size)");
    }

    return *temp;
}

// 遍历数组元素
template <class T>
void MyVector<T>::DisplayArrList()
{
    if (Data != NULL)
    {
        for (int i = 0; i < getSize(); i++)
        {
            cout << this->Data[i] << ",";
        }
        cout << endl;
    }
    else
    {
        throw out_of_range("数据为空");
    }
}

// 调整动态数组的容量
template <class T>
void MyVector<T>::reSize(int newCapacity)
{
    T *newData = new T[newCapacity];
    for (int i = 0; i < Size; i++)
    {
        newData[i] = Data[i];
    }
    Capacity = newCapacity;
    delete[] Data;
    Data = newData;
}

// 重载输出操作符<<
template <class U>
ostream &operator<<(ostream &os, const MyVector<U> &arr)
{
    for (int i = 0; i < arr.Size; i++)
    {
        os << arr[i] << ",";
    }
    os << endl;
    return os;
}
